package com.miplus.ccrm.core.service.crd;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.query.MPJLambdaQueryWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.miplus.ccrm.common.CmdResVo;
import com.miplus.ccrm.common.JPubUtils;
import com.miplus.ccrm.common.JSysUser;
import com.miplus.ccrm.core.controller.vo.credit.AssistListReqVo;
import com.miplus.ccrm.core.controller.vo.credit.AssistListResVo;
import com.miplus.ccrm.core.controller.vo.credit.CrdAssistantReqVo;
import com.miplus.ccrm.core.pojo.*;
import com.miplus.ccrm.core.service.conf.SysGrpService;
import com.miplus.ccrm.core.service.conf.SysUserService;
import com.miplus.ccrm.core.service.crd.FiCreditcaseAssistantService;
import com.miplus.ccrm.core.mapper.FiCreditcaseAssistantMapper;
import com.miplus.ccrm.core.utils.EnumFiCaseStatus;
import com.miplus.ccrm.core.utils.EnumGrpType;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author wangzl
 * @description 针对表【fi_creditcase_assistant(协催表)】的数据库操作Service实现
 * @createDate 2025-06-30 11:59:25
 */
@Service
public class FiCreditcaseAssistantServiceImpl extends MPJBaseServiceImpl<FiCreditcaseAssistantMapper, FiCreditcaseAssistant>
        implements FiCreditcaseAssistantService{

    @Resource
    FiCreditcasesService fiCreditcasesService;

    @Resource
    SysUserService sysUserService;

    @Resource
    SysGrpService sysGrpService;

    @Override
    public IPage<AssistListResVo> assistantList(JSysUser user, AssistListReqVo paras)
    {
        return selectJoinListPage(new Page<>(paras.getPageNum(),paras.getPageSize()),
                AssistListResVo.class,
                new MPJLambdaWrapper<FiCreditcaseAssistant>()
                        .leftJoin(FiCreditcases.class,FiCreditcases::getCreditcaseid,FiCreditcaseAssistant::getFicaseid)
                        .leftJoin(FiCreditcasesHist.class,FiCreditcasesHist::getHistid,FiCreditcaseAssistant::getAssignhistid)
                        .eq(JPubUtils.IsNotEmpty(paras.getFicaseid()),FiCreditcaseAssistant::getFicaseid,paras.getFicaseid())
                        .in(JPubUtils.IsNotEmpty(paras.getSendtodept()),FiCreditcaseAssistant::getSendtodept,paras.getSendtodept())
                        .in(JPubUtils.IsNotEmpty(paras.getSendtousr()),FiCreditcaseAssistant::getSendtousr,paras.getSendtousr())
                        .in(JPubUtils.IsNotEmpty(paras.getAssistant()),FiCreditcaseAssistant::getAssistant,paras.getAssistant())
                        .in(JPubUtils.IsNotEmpty(paras.getCrusr()),FiCreditcaseAssistant::getCrusr,paras.getCrusr())
                        .eq(JPubUtils.IsNotEmpty(paras.getStatus()),FiCreditcaseAssistant::getStatus,paras.getStatus())
                        .ge(JPubUtils.IsNotEmpty(paras.getStartdt1()),FiCreditcaseAssistant::getStartdt,paras.getStartdt1())
                        .le(JPubUtils.IsNotEmpty(paras.getStartdt2()),FiCreditcaseAssistant::getStartdt,paras.getStartdt2())
                        .ge(JPubUtils.IsNotEmpty(paras.getEnddt1()), FiCreditcaseAssistant::getEnddt,paras.getEnddt1())
                        .le(JPubUtils.IsNotEmpty(paras.getEnddt2()),FiCreditcaseAssistant::getEnddt,paras.getEnddt2())

                        .ge(JPubUtils.IsNotEmpty(paras.getClosedt1()),FiCreditcaseAssistant::getClosedt,paras.getClosedt1())
                        .le(JPubUtils.IsNotEmpty(paras.getClosedt2()),FiCreditcaseAssistant::getClosedt,paras.getClosedt2())

                        .ge(JPubUtils.IsNotEmpty(paras.getAssistdays1()),FiCreditcaseAssistant::getAssistdays,paras.getAssistdays1())
                        .le(JPubUtils.IsNotEmpty(paras.getAssistdays2()),FiCreditcaseAssistant::getAssistdays,paras.getAssistdays2())

                        .selectAll(FiCreditcaseAssistant.class)
                        .selectAs("fun_getusername(t.sendtousr)",AssistListResVo::getSendtousrname)
                        .selectAs("fun_getusername(t.assistant)",AssistListResVo::getAssistantname)
                        .selectAs("(select sg.grpname from sys_grp sg where sg.grpid=t.sendtodept)",AssistListResVo::getSendtodeptname)
                        .selectAs(FiCreditcasesHist::getCpTotalamt,AssistListResVo::getCpTotalamt)
                        .selectAs(FiCreditcasesHist::getMthsDay,AssistListResVo::getCpOverdueDays)
                        .orderByAsc(FiCreditcaseAssistant::getStatus)
                        .orderByDesc(FiCreditcasesHist::getCpTotalamt)
                        .orderByDesc(FiCreditcaseAssistant::getStartdt)
        );

    }
    @Override
    public CmdResVo addAssistant(String usrid, CrdAssistantReqVo para)
    {
        //首先判断是否满足条件。
        //1: 案件状态为已派工。
        //2: 协催人员和催员必须为同一机构。
        //3: 协催结束时间不能大于案件时间。
        //4: 催员和协催店不能相同。

        //获取催员你机构
        if(StringUtils.isEmpty(para.getAssistant()))
            return new CmdResVo(-1,"协催员不能为空");
        //获取协催员的机构ID。
        SysUser su = sysUserService.getById(para.getAssistant());

        SysGrp grp = sysGrpService.getById(su.getGroups());
        String deptId = grp.getGrpid();
        if(grp.getType() == EnumGrpType.TEAM.value){
            deptId = grp.getParentid();
        }
        List<AssistListResVo> fiCreditcases = fiCreditcasesService.getAssistCaseList( para.getFicaseids());
        CmdResVo v = checkAssistant(fiCreditcases,para, deptId);
        if( v.getCount() < 0){
            return v;
        }
        // 更新
        delAssistant(usrid, para);
        for(AssistListResVo x : fiCreditcases){
            FiCreditcaseAssistant fi = new FiCreditcaseAssistant();
            fi.setFicaseid( x.getFicaseid());
            fi.setSendtodept(x.getSendtodept());
            fi.setSendtousr(x.getSendtousr());
            fi.setAssistant(para.getAssistant());
            fi.setStartdt(para.getStartdt());
            fi.setEnddt(para.getEnddt());
            fi.setAssistdays(para.getAssistdays());
            fi.setAssignhistid(x.getAssignhistid());
            fi.setApplydt(new Date());
            fi.setApplyusr(usrid);
            fi.setApplydsc(para.getApplydsc());
            fi.setCrdt(new Date());
            fi.setCrusr(usrid);
            fi.setStatus(1);
            save(fi);
        }
        return new CmdResVo(fiCreditcases.size(),"执行成功！");
    }
    private CmdResVo checkAssistant(List<AssistListResVo> caselist, CrdAssistantReqVo para, String deptId)
    {
        //1: 案件状态为已派工。
        //2: 协催人员和催员必须为同一机构。
        //3: 协催结束时间不能大于案件时间。
        //4: 催员和协催店不能相同。
        if( caselist == null || caselist.size() == 0)
            return new CmdResVo(-1,"没有找到待处理的案件！");
        for(AssistListResVo x : caselist){
            if(JPubUtils.IsNotEmpty(x.getStatus()))
            {
                return new CmdResVo(-1,"案件"+x.getFicaseid() +"处于协催中！");
            }
            if( JPubUtils.IsEmpty(x.getSendtodept() )|| JPubUtils.IsEmpty(x.getSendtousr()))
                return new CmdResVo(-1,"案件"+x.getFicaseid() +"状态不正确，没有催员和机构信息！");
            if( !x.getCasestatus().equals(EnumFiCaseStatus.Assign.value))
                return new CmdResVo(-1,"案件"+x.getFicaseid() +"状态不正确，不是已派工状态！");
            String cpendtime = JPubUtils.DTimeToString(x.getCpEndTime()).substring(0,10);
            String enddt =JPubUtils.DTimeToString(para.getEnddt()).substring(0,10);
            if( cpendtime.compareTo(enddt) < 0)
            {
                return new CmdResVo(-1,"案件"+x.getFicaseid() +"委案结束时间大于协催结束时间");
            }
            if( !x.getSendtodept().equals(deptId))
            {
                return new CmdResVo(-1,"案件"+x.getFicaseid() +"委案机构和催员组织不同");
            }
            if( x.getSendtousr().equals(para.getAssistant()))
            {
                return new CmdResVo(-1,"案件"+x.getFicaseid() +"催员和协催员是同一人");
            }
        }
        return new CmdResVo(0);
    }
    /**
     * 删除协催员。
     * @param usrid
     * @param para
     * @return
     */
    @Override
    public CmdResVo delAssistant(String usrid, CrdAssistantReqVo para){
        if( para.getFicaseids() == null || para.getFicaseids().size() == 0)
        {
            return new CmdResVo(-1,"没有找到协催案件");
        }
        int cnt =  baseMapper.update(null,
                new UpdateWrapper<FiCreditcaseAssistant>().lambda()
                .in(FiCreditcaseAssistant::getFicaseid,para.getFicaseids())
                .setSql("closedt = case when enddt > now() then now() else enddt end")
                .set(FiCreditcaseAssistant::getCloseusr,usrid)
                .set(FiCreditcaseAssistant::getClosedsc,para.getClosedsc())
                .set(FiCreditcaseAssistant::getStatus,2)
        );
        return new CmdResVo(cnt,"协催取消成功");
    }
}




